package com.cf.base.http.generator.impl;

import com.alibaba.fastjson.JSONException;
import com.cf.base.http.bean.ErrorResponse;
import com.cf.base.http.core.RetrofitService;
import com.cf.base.http.engine.JsonEngine;
import com.cf.base.http.exception.CFHttpException;
import com.cf.base.http.exception.CFHttpTimeoutException;
import com.cf.base.http.exception.CFJsonException;
import com.cf.base.http.exception.CFServerException;
import com.cf.base.http.exception.ExceptionCode;
import com.cf.base.http.generator.BaseBodyErrorAdapter;
import com.cf.base.http.utils.TextUtils;

import java.io.IOException;
import java.lang.reflect.Method;
import java.net.ConnectException;
import java.net.UnknownHostException;

import okhttp3.ResponseBody;
import retrofit2.HttpException;
import retrofit2.Response;

/**
 * @author yangji
 */
public abstract class DefaultBodyErrorAdapter<T extends ErrorResponse> extends BaseBodyErrorAdapter<T> {

    private JsonEngine engine;

    private JsonEngine getEngine() {
        return engine;
    }

    protected DefaultBodyErrorAdapter(JsonEngine engine) {
        this.engine = engine;
    }

    @Override
    public Throwable call(RetrofitService bean, Method method, Throwable throwable) {
        if (throwable instanceof UnknownHostException) {
            //域名解析失败
            return new CFHttpException(throwable, ExceptionCode.CODE_CONNECT_ERROR, "域名解析错误");
        }

        //如果设置的
        // 第三方网站 网络异常
        // CF connectTimeout、readTimeout、writeTimeout 时间太短有可能出现是网络异常
        if (throwable instanceof ConnectException) {
            return new CFHttpException(throwable, ExceptionCode.CODE_CONNECT_ERROR, "网络连接异常");
        }

        if (throwable instanceof java.net.SocketTimeoutException) {
            return new CFHttpTimeoutException(throwable, ExceptionCode.CODE_TIMEOUT_ERROR, "网络 connectTimeout/readTimeout 超时");
        }

        if (throwable instanceof java.io.InterruptedIOException) {
            return new CFHttpTimeoutException(throwable, ExceptionCode.CODE_TIMEOUT_ERROR, "网络 callTimeout 超时");
        }
        if (throwable instanceof IllegalArgumentException) {
            return new CFHttpTimeoutException(throwable, ExceptionCode.CODE_TIMEOUT_ERROR, "网络配置时间太少");
        }
        ////解析
        if (throwable instanceof JSONException) {
            return new CFJsonException(throwable, ExceptionCode.CODE_PARSING_ERROR, "fastJson 解析异常");
        }

        if (throwable instanceof org.json.JSONException) {
            return new CFJsonException(throwable, ExceptionCode.CODE_PARSING_ERROR, "org.json 解析异常");
        }

        if (throwable instanceof com.google.gson.stream.MalformedJsonException) {
            return new CFJsonException(throwable, ExceptionCode.CODE_PARSING_ERROR, "Gson 解析异常");
        }

        //如果不是服务器异常 直接抛出异常
        if (!(throwable instanceof HttpException)) {
            return throwable;
        }

        HttpException error = (HttpException) throwable;
        Response res = error.response();
        if (res != null) {
            int code = res.code();
            String message = res.message();
            ResponseBody responseBody = res.errorBody();
            if (responseBody != null) {
                try {
                    String string = responseBody.string();
                    if (string.length() > 0) {
                        T t = getEngine().toObject(string, getBaseClass());
                        if (t.getCode() != -1) {
                            code = t.getCode();
                        }
                        if (!TextUtils.isEmpty(t.getMessage())) {
                            message = t.getMessage();
                        }

                        return new CFServerException(throwable, code, message, t);
                    }

                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            return new CFServerException(throwable, code, "服务器炸了");
        }
        return new CFServerException(throwable, error.code(), error.getMessage());
    }
}
